package com.szl.yeb.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.szl.yeb.common.R;
import com.szl.yeb.dto.MenuDto;
import com.szl.yeb.entity.MenuRole;
import com.szl.yeb.mapper.MenuMapper;
import com.szl.yeb.entity.Menu;
import com.szl.yeb.mapper.MenuRoleMapper;
import com.szl.yeb.service.MenuService;
import com.szl.yeb.utils.AdminUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import com.szl.yeb.common.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.szl.yeb.utils.MybatisPlusUtil;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * (Menu)表服务实现类
 *
 * @author szl
 * @since 2022-08-24 16:21:26
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private MenuRoleMapper menuRoleMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public PageResult getPage(Integer currentPage, Integer size, Menu menu) {
        Page<Menu> page = new Page<>(currentPage, size);

        QueryWrapper<Menu> queryWrapper = MybatisPlusUtil.queryWrapperBuilder(menu);

        this.page(page, queryWrapper);

        return new PageResult((int) page.getTotal(), page.getRecords());
    }

    @Override
    public R<Object> getMenusByAdminId() {
        ValueOperations<String, Object> operations = redisTemplate.opsForValue();

        Integer adminId = AdminUtil.getCurrentAdmin().getId();

        List<Menu> adminMenus = Convert.toList(Menu.class, operations.get("menu_" + adminId));

        if (adminMenus == null || adminMenus.size() <= 0) {
            List<Menu> menus = menuMapper.getMenusByAdminId(adminId,1);
            operations.set("menu_" + adminId, menus);
            return R.obj(menus);
        }

        return R.obj(Convert.toList(Menu.class, adminMenus));
    }

    @Override
    public List<Menu> getMenusWithRoles() {
        return menuMapper.selectMenusWithRoles();
    }

    @Override
    public List<Menu> getMenusWithChildren() {
        return menuMapper.selectMenusWithChildren();
    }

    @Override
    public List<Integer> getMenusFromRoleId(Integer rid) {
        return menuRoleMapper.selectList(MybatisPlusUtil.getLQWrapper(MenuRole.class).eq(MenuRole::getRid, rid))
                .stream().map(MenuRole::getMid).collect(Collectors.toList());
    }

    @Override
    public List<Menu> getMenusWithChildrenWithFullData() {
        return menuMapper.MenusWithChildrenWithFullData(null);
    }

    @Override
    @Transactional
    public Boolean addMenu(Menu menu) {
        menu.setEnabled(1).setIsParent(false).setRequireAuth(1);

        Menu parentMenu = new Menu();
        parentMenu.setId(menu.getParentId()).setIsParent(true);
        baseMapper.updateById(parentMenu);

        baseMapper.insert(menu);

        Integer adminId = AdminUtil.getCurrentAdmin().getId();
        redisTemplate.delete("menu_" + adminId);

        return true;
    }

    @Override
    @Transactional
    public Boolean updateMenu(MenuDto menuDto) {

        Menu parentMenu = new Menu();
        parentMenu.setId(menuDto.getParentId()).setIsParent(true);
        baseMapper.updateById(parentMenu);

        Menu menu = new Menu();
        BeanUtils.copyProperties(menuDto, menu);
        baseMapper.updateById(menu);

        Long count = baseMapper.selectCount(MybatisPlusUtil.getLQWrapper(Menu.class).eq(Menu::getParentId, menuDto.getOldParentId()));
        if (count == 0) {
            parentMenu.setId(menuDto.getOldParentId()).setIsParent(false);
            baseMapper.updateById(parentMenu);
        }

        Integer adminId = AdminUtil.getCurrentAdmin().getId();
        redisTemplate.delete("menu_" + adminId);

        return true;
    }

    @Override
    @Transactional
    public Boolean deleteMenu(Integer id, Integer parentId) {
        baseMapper.deleteById(id);
        Long count = baseMapper.selectCount(MybatisPlusUtil.getLQWrapper(Menu.class).eq(Menu::getParentId, parentId));
        if (count == 0) {
            Menu parentMenu = new Menu();
            parentMenu.setId(parentId).setIsParent(false);
            baseMapper.updateById(parentMenu);
        }

        Integer adminId = AdminUtil.getCurrentAdmin().getId();
        redisTemplate.delete("menu_" + adminId);

        return true;
    }
}

